'''
@since: 23.03.2014

@author: Max

@summary: Diese Klasse ost verantwortlich fuer die Arbeiter
'''

from gfx.Tileset import *
from Properties import *
from Solids import *

import copy
import math

class Worker(object):
    nextId = 0
    
    def __init__(self, pos, map, clock):
        """@ivar: ID zur Identifikation"""
        self.myID = id
        
        self.pos = pos
        """@ivar: Position des Arbeiters"""
        
        self.dest = (10, 10)
        """@ivar: Ziel-Tile"""
        
        self.inv = None
        """@ivar: Gibt an, welches Paket der Arbeiter traegt"""
        
        self.path = ()
        """@ivar: Weg des Arbeiters"""
        
        self.nextPos = None
        """@ivar: Naechste Position des Arbeiters, fuer den Baustopp"""
        
        self.currentPos = 0
        
        self.image = pygame.image.load(RESOURCES_WORKER_IMAGE).convert_alpha()
        
        self.startTime = 0
        
        self.currentTime = 0
        
        self.nextId += 1
        
        self.delay = 100
        
        self.map = map
        
        
    def astar(self):
        """
        Diese Funktion uebernimmt die Pfadberechnung des Arbeiters zu einem bestimmten Ziel
        """
        props = self.map.arMapProps
        
        self.closedList = []
        openList = []
        path = {}
        gScore = {}
        fScore = {}
        
        gScore[self.pos] = 0
        fScore[self.pos] = gScore[self.pos] + self.heuristic(self.pos)
        
        openList.append(self.pos)
        while len(openList) != 0:
            current = openList[0]
            for elem in openList:
                if fScore[elem] < fScore[current]:
                    current = elem

            if current == self.dest:
                self.path = self.reconstructPath(path, self.dest)
                self.startTime = pygame.time.get_ticks()
            
            self.closedList.append(current)
            openList.remove(current)
            
            neighbors = self.calculateNeighbors(current, props)
            
            for elem in neighbors:
                if elem in self.closedList:
                    continue
                tentGscore = fScore[current] + self.dist(current, elem)
                
                if elem not in openList or tentGscore < gScore[elem]:
                    path[elem] = current
                    gScore[elem] = tentGscore
                    fScore[elem] = gScore[elem] + self.heuristic(elem)
                    if elem not in openList:
                        openList.append(elem)
                      
            
    def calculateNeighbors(self, current, props):
        cands = [
                 (current[0] - 1, current[1] - 1),
                 (current[0] - 1, current[1]),
                 (current[0] - 1, current[1] + 1),
                 (current[0], current[1] - 1),
                 (current[0], current[1] + 1),
                 (current[0] + 1, current[1] - 1),
                 (current[0] + 1, current[1]),
                 (current[0] + 1, current[1] + 1)
                 ]
        
        candsCopy = copy.deepcopy(cands)

        for elem in candsCopy:
            if elem[0] < 0:
                cands.remove(elem)
                continue
            elif elem[1] < 0:
                cands.remove(elem)
                continue
            elif elem[0] > MAP_ROWS:
                cands.remove(elem)
                continue
            elif elem[1] > MAP_COLS:
                cands.remove(elem)
                continue

        
        for elem in cands:
            for entry in props:
                if entry.pos == elem:
                    self.closedList.append(elem)
                 
        return cands
                    
                
    def dist(self, a, b):
        return math.sqrt((b[0] + a[0]) ** 2 + (b[1] + a[1]) ** 2)    
                
    def reconstructPath(self, path, dest):
        if dest in path:
            p = self.reconstructPath(path, path[dest])
            return p + dest
        else:
            return dest
    
    def heuristic(self, current):
        return math.sqrt((current[0] + self.dest[0]) ** 2 + (current[1] + self.dest[1]) ** 2)
    
    def update(self):
        self.currentTime = pygame.time.get_ticks()
        if len(self.path) > 0:
            if self.currentTime - self.startTime >= self.delay:
                self.calculateNewPos();
                self.startTime = pygame.time.get_ticks()
            
    
    def calculateNewPos(self):
        self.pos = self.path[0:2]
        self.path = self.path[2:]
        print len(self.path)
        
